import './App.css';
import { useState, useEffect, useRef } from 'react';
const cg = [['a', 1], ['b', 2], ['c', 3], ['d', 4], ['e', 5], ['f', 6], ['g', 7]];
const bgm = [require('./timi.mp3'), require('./xc.mp3'),]
const App = () => {
  const [data, setData] = useState([])
  const [origin, setOrigin] = useState([4, 1])
  const [music, setMusic] = useState('');
  const intervalRef = useRef();
  const icons = useRef();
  const roatnums = useRef();
  const alls = useRef([]);
  const [code, setCode] = useState(0)
  const num = useRef(0);
  const [gameover, setGameover] = useState();
  const [rownum, setRow] = useState(12);
  const [columnnum, setCol] = useState(6)
  useEffect(() => {
    init();
  }, [rownum, columnnum])
  const clearAll = () => {
    clearInterval(intervalRef.current)
    setData([]);
    icons.current = [];
    roatnums.current = 0;
    num.current = 0;
    columnnum % 2 === 0 ? origin[0] = parseInt(columnnum / 2) : origin[0] = parseInt(columnnum / 2) + 1;
    origin[1] = 0;
    setOrigin(origin)
  }
  //随机生成方块
  function suiji() {
    clearAll();
    let ic = [];
    let nm;
    let sj = Math.random();
    let sz = Math.random();
    sj = Math.ceil(sj * 7);
    sz = Math.ceil(sz * 4)
    for (let i = 0; i < cg.length; i++) {
      if (cg[i][1] === sj) {
        nm = cg[i][0];
      }
    }
    ic = fangkuai(nm);//生成对应方块
    for (let i = 0; i < sz; i++) {
      ic = rolate(ic, i);
    }
    roatnums.current = sz;
    icons.current = ic;
    change(ic[0]);
    let i = 0;
    let id = setInterval(async () => {
      await tdown();
      if (num.current === 0 && i === 0) {
        setGameover(`游戏结束,您的最终得分为：`)
        clearInterval(intervalRef.current);
      }
      i++;
    }, 700)
    intervalRef.current = id;
  }
  //初始化方块
  const fangkuai = (nm) => {
    let ic = [];
    if (nm === 'a') {
      ic = icon1(origin[0], origin[1]);
    } else if (nm === 'b') {
      ic = icon2(origin[0], origin[1]);
    } else if (nm === 'c') {
      ic = icon3(origin[0], origin[1]);
    } else if (nm === 'd') {
      ic = icon4(origin[0], origin[1]);
    } else if (nm === 'e') {
      ic = icon5(origin[0], origin[1]);
    } else if (nm === 'f') {
      ic = icon6(origin[0], origin[1]);
    } else if (nm === 'g') {
      ic = icon7(origin[0], origin[1]);
    }
    return ic;
  }
  //初始化表格
  function init() {
    let ttr = [], ttd = [];
    // 初始化行内容
    for (let i = 0; i < columnnum; i++) {
      ttd.push({});
    }
    // 初始化列内容
    for (let i = 0; i < rownum; i++) {
      ttd = JSON.parse(JSON.stringify(ttd))
      ttr.push(ttd);
    }
    setData(ttr);
    return ttr;
  }
  //改变表格颜色
  function change(ic) {
    let all = alls.current;
    let datas = init();
    for (let j = 0; j < all.length; j++) {
      for (let i = 0; i < all[j].length; i++) {
        if (all[j][i][1] > -1 && all[j][i][0] > -1 && all[j][i].length > 0) {
          datas[all[j][i][1]][all[j][i][0]] = all[j][i][2];
        }
      }
    }
    for (let i = 0; i < ic.length; i++) {
      if (ic[i][1] > -1 && ic[i][0] > -1) {
        datas[ic[i][1]][ic[i][0]] = ic[i][2];
      }
    }
    setData(datas);
  }
  //消除满行
  function xiaochu() {
    let icon = icons.current;
    let all = alls.current;
    if (all.length > 1) {
      //满行numjj+1
      let numjj = [];
      let al = all;
      if (numjj.length === 0) {
        let guige = [];
        let q = 0;
        for (let o = 0; o < all.length; o++) {
          for (let p = 0; p < all[o].length; p++) {
            guige[q] = [all[o][p][0], all[o][p][1]];
            q++;
          }
        }
        for (let i = rownum - 1; i >= 0; i--) {
          let jsq = columnnum;
          for (let k = 0; k < guige.length; k++) {
            if (guige[k][1] === i) jsq--;
          }
          if (jsq === 0) numjj.push(i);
        }
        //满行信息重置为空
        if (numjj.length > 0) {
          for (let n = 0; n < numjj.length; n++) {
            for (let l = 0; l < al.length; l++) {
              for (let m = 0; m < al[l].length; m++) {
                if (al[l][m][1] === numjj[n]) {
                  al[l][m] = [];
                }
              }
            }
          }
          alls.current = al;
          change(icon[0]);
          setMusic(bgm[roatnums.current % bgm.length])
          setTimeout(() => {
            setMusic('')
          }, 1000)
          //判断下移量
          if (numjj.length === 4) {
            for (let o = 0; o < al.length; o++) {
              for (let p = 0; p < al[o].length; p++) {
                if (al[o][p][1] < numjj[3]) {
                  al[o][p][1] = al[o][p][1] + 4;
                }
              }
            }
          } else if (numjj.length === 1) {
            for (let o = 0; o < al.length; o++) {
              for (let p = 0; p < al[o].length; p++) {
                if (al[o][p].length > 0 && al[o][p][1] < numjj[0]) {
                  al[o][p][1] = al[o][p][1] + 1;
                }
              }
            }
          } else if (numjj.length === 2) {
            for (let o = 0; o < al.length; o++) {
              for (let p = 0; p < al[o].length; p++) {
                if (al[o][p][1] < numjj[0] && al[o][p][1] > numjj[1]) {
                  al[o][p][1] = al[o][p][1] + 1;
                }
                if (al[o][p][1] < numjj[1]) {
                  al[o][p][1] = al[o][p][1] + 2;
                }
              }
            }
          } else if (numjj.length === 3) {
            for (let o = 0; o < al.length; o++) {
              for (let p = 0; p < al[o].length; p++) {
                if (al[o][p][1] < numjj[0] && al[o][p][1] > numjj[1]) {
                  al[o][p][1] = al[o][p][1] + 1;
                }
                if (al[o][p][1] < numjj[1] && al[o][p][1] > numjj[2]) {
                  al[o][p][1] = al[o][p][1] + 2;
                }
                if (al[o][p][1] < numjj[3]) {
                  al[o][p][1] = al[o][p][1] + 3;
                }
              }
            }
          }
          setCode(code + 10 * numjj.length)
          alls.current = al;
          change(icon[0]);
        }
      }
    }
  }
  //判断是否触底
  //向下移动
  const tdown = () => {
    let ic = icons.current;
    let all = alls.current;
    let id = false;
    //判断是否已经触底
    for (let i = 0; i < ic[0].length; i++) {
      if (id) return 0;
      if (ic[0][i][1] === rownum - 1) {
        id = true;
        return 0;
      }
    }
    if (!id) {
      let og = origin;
      og[1] = og[1] + 1;
      setOrigin(og);
      init();
      ic = fangkuai(ic[1]);
      for (let i = 0; i < roatnums.current; i++) {
        ic = rolate(ic, i)
      }
      //判断下降一格是否触底
      for (let i = 0; i < ic[0].length; i++) {
        if (id) return 0;
        if (ic[0][i][1] === rownum - 1) {
          let al = all;
          al.push(ic[0])
          alls.current = al;
          suiji();
          id = true;
          return 2;
        }
        //判断下降一格是否接触其他方块
        for (let k = 0; k < all.length; k++) {
          if (id) return 0;
          for (let j = 0; j < all[k].length; j++) {
            if (ic[0][i][1] + 1 === all[k][j][1] && ic[0][i][0] === all[k][j][0]) {
              let al = all;
              al.push(ic[0])
              alls.current = al;
              suiji();
              id = true;
              return 2;
            }
          }
        }
      }
      if (!id) {
        num.current = num.current + 1;
        icons.current = ic;
        change(ic[0]);
        xiaochu()
        return 0;
      }
    }
  }
  //向左移动
  //判断左边界
  const tleft = () => {
    let icon = icons.current;
    let all = alls.current;
    let id = false;
    if (id) return 0;
    for (let i = 0; i < icon[0].length; i++) {
      if (id) return 0;
      if (icon[0][i][0] - 1 < 0 || origin[0] === 0) {
        id = true;
        return 0;
      }
    }
    for (let x = 0; x < icon[0].length; x++) {
      icon[0][x][0] = icon[0][x][0] - 1;
      for (let y = 0; y < all.length; y++) {
        for (let z = 0; z < all[y].length; z++) {
          if (icon[0][x][0] === all[y][z][0] && icon[0][x][1] === all[y][z][1]) {
            id = true;
            return 0;
          }
        }
      }
    }
    if (!id) {
      let og = origin;
      og[0] = og[0] - 1;
      setOrigin(og)
      init();
      let ic = fangkuai(icon[1]);
      for (let i = 0; i < roatnums.current; i++) {
        ic = rolate(ic, i)
      }
      icons.current = ic;
      change(ic[0]);
    }
  }
  //向右移动
  //判断右边界
  const tright = () => {
    let icon = icons.current;
    let all = alls.current;
    let id = false;
    if (id) return 0;
    for (let i = 0; i < icon[0].length; i++) {
      if (id) return 0;
      if (icon[0][i][0] + 1 >= columnnum || origin[0] === columnnum - 1) {
        id = true;
        return 0;
      }
    }
    for (let x = 0; x < icon[0].length; x++) {
      icon[0][x][0] = icon[0][x][0] + 1;
      for (let y = 0; y < all.length; y++) {
        for (let z = 0; z < all[y].length; z++) {
          if (icon[0][x][0] === all[y][z][0] && icon[0][x][1] === all[y][z][1]) {
            id = true;
            return 0;
          }
        }
      }
    }
    if (!id) {
      let og = origin;
      og[0] = og[0] + 1;
      setOrigin(og)
      init();
      let ic = fangkuai(icon[1]);
      for (let i = 0; i < roatnums.current; i++) {
        ic = rolate(ic, i)
      }
      icons.current = ic;
      change(ic[0]);
    }
  }
  //向切换上方向
  const tup = () => {
    let icon = icons.current;
    let all = alls.current;
    let id = false;
    if (icon[1] === 'e') return 0;
    if (icon[1] === 'd' && origin[0] === columnnum - 2) return 0;
    if (id) return 0;
    for (let i = 0; i < icon[0].length; i++) {
      if (id) return 0;
      if (icon[0][i][0] + 1 > columnnum || icon[0][i][0] < 0 || origin[0] === columnnum - 1 || origin[0] === 0) {
        id = true;
        return 0;
      }
    }
    if (!id) {
      let num = rolate(icon, roatnums.current)
      for (let x = 0; x < num[0].length; x++) {
        for (let y = 0; y < all.length; y++) {
          for (let z = 0; z < all[y].length; z++) {
            if (num[0][x][0] === all[y][z][0] && num[0][x][1] === all[y][z][1]) {
              id = true;
              return 0;
            }
          }
        }
      }
      if (icon !== num && origin[0] !== 0 && !id) {
        init();
        let ic = fangkuai(icon[1]);
        let sz = roatnums.current + 1;
        for (let i = 0; i < sz; i++) {
          ic = rolate(ic, i)
        }
        for (let i = 0; i < ic[0].length; i++) {
          if (id) return 0;
          if (ic[0][i][1] === rownum - 1) {
            let al = all;
            al.push(ic[0])
            alls.current = al;
            suiji();
            id = true;
            return 0;
          }
          for (let k = 0; k < all.length; k++) {
            if (id) return 0;
            for (let j = 0; j < all[k].length; j++) {
              if (ic[0][i][1] + 1 === all[k][j][1] && ic[0][i][0] === all[k][j][0]) {
                let al = all;
                al.push(ic[0])
                alls.current = al;
                suiji();
                id = true;
                return 0;
              }
              if (ic[0][i][1] === all[k][j][1] && ic[0][i][0] === all[k][j][0]) {
                id = true;
                return 0;
              }
            }
          }
        }
        if (!id) {
          icons.current = ic;
          roatnums.current = sz;
          change(icon[0]);
        }
      }
    }
  }
  //监听事件
  window.onkeydown = (e) => {
    if (e.key === "ArrowDown") {
      tdown();
    } else if (e.key === "ArrowLeft") {
      tleft();
    } else if (e.key === "ArrowRight") {
      tright();
    } else if (e.key === "ArrowUp") {
      tup();
    }
  }
  //方块旋转 
  const rolate = (icon, nn) => {
    let ic = icon[0];
    let on = icon[1];
    if (on === 'e') {
      return icon;
    } else if (on === 'b') {
      if (nn % 2 === 0) {
        for (let i = 0; i < ic.length; i++) {
          if (ic[i][0] - origin[0] === -1 && ic[i][1] - origin[1] === -1) {
            ic[i][1] = ic[i][1] + 2;
          } else if (ic[i][0] - origin[0] === 0 && ic[i][1] - origin[1] === -1) {
            ic[i][0] = ic[i][0] - 1;
            ic[i][1] = ic[i][1] + 1;
          } else if (ic[i][0] - origin[0] === 1 && ic[i][1] - origin[1] === 0) {
            ic[i][0] = ic[i][0] - 1;
            ic[i][1] = ic[i][1] - 1;
          }
        }
      } else {
        for (let i = 0; i < ic.length; i++) {
          if (ic[i][0] - origin[0] === -1 && ic[i][1] - origin[1] === 1) {
            ic[i][1] = ic[i][1] - 2;
          } else if (ic[i][0] - origin[0] === 0 && ic[i][1] - origin[1] === -1) {
            ic[i][0] = ic[i][0] + 1;
            ic[i][1] = ic[i][1] + 1;
          } else if (ic[i][0] - origin[0] === -1 && ic[i][1] - origin[1] === 0) {
            ic[i][0] = ic[i][0] + 1;
            ic[i][1] = ic[i][1] - 1;
          }
        }
      }
      return [ic, on];
    } else if (on === 'g') {
      if (nn % 2 === 0) {
        for (let i = 0; i < ic.length; i++) {
          if (ic[i][0] - origin[0] === -1 && ic[i][1] - origin[1] === 0) {
            ic[i][0] = ic[i][0] + 1;
            ic[i][1] = ic[i][1] + 1;
          } else if (ic[i][0] - origin[0] === 0 && ic[i][1] - origin[1] === -1) {
            ic[i][0] = ic[i][0] - 1;
            ic[i][1] = ic[i][1] + 1;
          } else if (ic[i][0] - origin[0] === 1 && ic[i][1] - origin[1] === -1) {
            ic[i][0] = ic[i][0] - 2;
          }
        }
      } else {
        for (let i = 0; i < ic.length; i++) {
          if (ic[i][0] - origin[0] === -1 && ic[i][1] - origin[1] === -1) {
            ic[i][0] = ic[i][0] + 2;
          } else if (ic[i][0] - origin[0] === -1 && ic[i][1] - origin[1] === 0) {
            ic[i][0] = ic[i][0] + 1;
            ic[i][1] = ic[i][1] - 1;
          } else if (ic[i][0] - origin[0] === 0 && ic[i][1] - origin[1] === 1) {
            ic[i][0] = ic[i][0] - 1;
            ic[i][1] = ic[i][1] - 1;
          }
        }
      }
      return [ic, on];
    } else if (on === 'd') {
      for (let i = 0; i < ic.length; i++) {
        if (ic[i][0] - origin[0] === 2 && ic[i][1] - origin[1] === 0) {
          ic[i][0] = ic[i][0] - 2;
          ic[i][1] = ic[i][1] + 2;
        } else if (ic[i][0] - origin[0] === 0 && ic[i][1] - origin[1] === 2) {
          if (ic[i][0] + 2 >= columnnum) return icon;
          ic[i][0] = ic[i][0] + 2;
          ic[i][1] = ic[i][1] - 2;
        }
      }
    }
    for (let i = 0; i < ic.length; i++) {
      if (ic[i][0] - origin[0] === 0 && ic[i][1] - origin[1] === 1) {
        ic[i][0] = ic[i][0] - 1;
        ic[i][1] = ic[i][1] - 1;
      } else if (ic[i][0] - origin[0] === -1 && ic[i][1] - origin[1] === 0) {
        ic[i][0] = ic[i][0] + 1;
        ic[i][1] = ic[i][1] - 1;
      } else if (ic[i][0] - origin[0] === 0 && ic[i][1] - origin[1] === -1) {
        ic[i][0] = ic[i][0] + 1;
        ic[i][1] = ic[i][1] + 1;
      } else if (ic[i][0] - origin[0] === 1 && ic[i][1] - origin[1] === 0) {
        ic[i][0] = ic[i][0] - 1;
        ic[i][1] = ic[i][1] + 1;
      } else if (ic[i][0] - origin[0] === -1 && ic[i][1] - origin[1] === -1) {
        ic[i][0] = ic[i][0] + 2;
      } else if (ic[i][0] - origin[0] === 1 && ic[i][1] - origin[1] === -1) {
        ic[i][1] = ic[i][1] + 2;
      } else if (ic[i][0] - origin[0] === 1 && ic[i][1] - origin[1] === 1) {
        ic[i][0] = ic[i][0] - 2;
      } else if (ic[i][0] - origin[0] === -1 && ic[i][1] - origin[1] === 1) {
        ic[i][1] = ic[i][1] - 2;
      }
    }
    return [ic, on];
  }

  //icon1 {state:'greenyellow'}
  //  www
  //    w
  //    w
  const icon1 = (x, y) => {
    let icon = [];
    icon[0] = [x - 1, y - 1];
    icon[1] = [x, y - 1];
    icon[2] = [x, y];//原点
    icon[3] = [x, y + 1];
    for (let i = 0; i < icon.length; i++) icon[i][2] = { state: 'greenyellow' };
    return [icon, 'a'];
  }
  //icon2 {state: 'rgba(129, 233, 236, 0.459)'}
  //  wwww
  //    wwww
  const icon2 = (x, y) => {
    let icon = [];
    icon[0] = [x - 1, y - 1];
    icon[1] = [x, y - 1];
    icon[2] = [x, y];//原点
    icon[3] = [x + 1, y];
    for (let i = 0; i < icon.length; i++) icon[i][2] = { state: 'rgba(129, 233, 236, 0.459)' };
    return [icon, 'b'];
  }
  //icon3 {state: 'rgb(85, 177, 238)'}
  //     ww
  //   wwwwww
  const icon3 = (x, y) => {
    let icon = [];
    icon[0] = [x, y - 1];
    icon[1] = [x - 1, y];
    icon[2] = [x, y];//原点
    icon[3] = [x + 1, y];
    for (let i = 0; i < icon.length; i++) icon[i][2] = { state: 'rgb(85, 177, 238)' };
    return [icon, 'c'];
  }
  //icon4 {state: 'rgba(221, 242, 180, 0.459)'}
  //   ww ww ww ww
  const icon4 = (x, y) => {
    let icon = [];
    icon[0] = [x - 1, y];
    icon[1] = [x, y];//原点
    icon[2] = [x + 1, y];
    icon[3] = [x + 2, y];
    for (let i = 0; i < icon.length; i++) icon[i][2] = { state: 'rgba(221, 242, 180, 0.459)' };
    return [icon, 'd'];
  }
  //icon5 {state: 'rgba(221, 239, 106, 0.459)'}
  //   ww ww
  //   ww ww
  const icon5 = (x, y) => {
    let icon = [];
    icon[0] = [x - 1, y - 1];
    icon[1] = [x, y - 1];
    icon[2] = [x - 1, y];
    icon[3] = [x, y];//原点
    for (let i = 0; i < icon.length; i++) icon[i][2] = { state: 'rgba(221, 239, 106, 0.459)' };
    return [icon, 'e'];
  }
  //icon6 {state: 'rgba(95, 181, 90, 0.459)'}
  //    www
  //    w
  //    w
  const icon6 = (x, y) => {
    let icon = [];
    icon[0] = [x - 1, y + 1];
    icon[1] = [x, y - 1];
    icon[2] = [x, y];//原点
    icon[3] = [x, y + 1];
    for (let i = 0; i < icon.length; i++) icon[i][2] = { state: 'rgba(95, 181, 90, 0.459)' };
    return [icon, 'f'];
  }
  //icon7 {state: 'rgba(239, 179, 106, 0.459)'}
  //   wwww
  // wwww
  const icon7 = (x, y) => {
    let icon = [];
    icon[0] = [x, y - 1];
    icon[1] = [x + 1, y - 1];
    icon[2] = [x, y];//原点
    icon[3] = [x - 1, y];
    for (let i = 0; i < icon.length; i++) icon[i][2] = { state: 'rgba(239, 179, 106, 0.459)' };
    return [icon, 'g'];
  }
  const play = () => {
    alls.current = [];
    setGameover(null)
    suiji();
  }
  return (
    <div style={{ backgroundColor: '#fff', textAlign: 'center' }}>
      <div style={{ display: 'flex',justifyContent:'space-around',alignItems:'center', width: columnnum * 60, margin: 'auto', marginTop: 30, marginBottom: 30 }}>
        <div style={{ display: 'flex',justifyContent:'center',alignItems:'center' }}>
          <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', borderRadius: 10, lineHeight: '50px', width: columnnum * 15, height: 50, backgroundColor: 'pink', margin: 'auto' }}>游戏行数</div>
          <input onChange={(e) => { clearAll(); init(); e.target.value >= 12 && e.target.value <= 40 ? setRow(e.target.value) : console.log(e.target.valueAsNumber); }} type='number' min={12} max={40} placeholder='12~40' style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', lineHeight: '50px', width:80, height: 30, margin: 'auto' }} />
        </div>
        <div style={{ display: 'flex',justifyContent:'center',alignItems:'center'}}>
          <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', borderRadius: 10, lineHeight: '50px', width: columnnum * 15, height: 50, backgroundColor: 'pink', margin: 'auto' }}>游戏列数</div>
          <input onChange={(e) => { clearAll(); init(); e.target.value >= 6 && e.target.value <= 40 ? setCol(e.target.value) : console.log(e.target.valueAsNumber); }} type='number' min={6} mar={40} placeholder='6~40' style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', lineHeight: '50px', width: 80, height: 30, margin: 'auto' }} />
        </div>
      </div>
      <table style={{ width: columnnum * 60, height: rownum * 63, margin: 'auto', }}>
        <tbody>
          {data.map((ite, ind) => {
            return <tr key={ind} className='row'>
              {ite.map((item, i) => {
                return <td key={i} style={{ width: 40, height: 40, border: '2px solid rgb(155, 149, 149)', backgroundColor: item.state }}></td>
              })}
            </tr>
          })}
        </tbody>
      </table>
      <div style={{ color: '#fff', borderRadius: 20, opacity: 0.9, fontSize: 30, lineHeight: '200px', backgroundColor: 'pink', position: 'fixed', top: rownum * 20, width: '20%', height: 200, left: '40%', display: gameover ? 'block' : 'none' }}>{gameover}{gameover ? code : ''}</div>
      <audio src={require('./bg.mp3')} autoPlay loop></audio>
      <audio src={music} autoPlay ></audio>
      <div style={{ display: 'flex', width: columnnum * 60, margin: 'auto', marginTop: 30 }}>
        <div onClick={play} style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', borderRadius: 10, lineHeight: '50px', width: columnnum * 20, height: 50, backgroundColor: 'pink', margin: 'auto' }}>开始游戏</div>
        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', borderRadius: 10, lineHeight: '50px', width: columnnum * 20, height: 50, backgroundColor: 'pink', margin: 'auto' }}>当前得分：{code}</div>
      </div>
    </div>
  );
}

export default App;
